Apgūstiet tīmekļa veiktspēju, analizējot un optimizējot kritisko renderēšanas ceļu. Visaptveroša rokasgrāmata izstrādātājiem par to, kā JavaScript ietekmē renderēšanu un kā to uzlabot.
JavaScript veiktspējas optimizācija: padziļināta izpēte par kritisko renderēšanas ceļu
Tīmekļa izstrādes pasaulē ātrums nav tikai funkcija; tas ir labas lietotāja pieredzes pamats. Lēni ielādējoša vietne var novest pie augstākiem atlēcienu rādītājiem, zemākām konversijām un neapmierinātas auditorijas. Lai gan tīmekļa veiktspēju ietekmē daudzi faktori, viens no fundamentālākajiem un bieži pārprastajiem jēdzieniem ir kritiskais renderēšanas ceļš (CRP). Izpratne par to, kā pārlūkprogrammas renderē saturu un, vēl svarīgāk, kā JavaScript mijiedarbojas ar šo procesu, ir ļoti svarīga ikvienam izstrādātājam, kurš nopietni uztver veiktspēju.
Šī visaptverošā rokasgrāmata jūs aizvedīs padziļinātā ceļojumā pa kritisko renderēšanas ceļu, īpaši koncentrējoties uz JavaScript lomu. Mēs izpētīsim, kā to analizēt, identificēt vājās vietas un pielietot jaudīgas optimizācijas metodes, kas padarīs jūsu tīmekļa lietojumprogrammas ātrākas un atsaucīgākas globālai lietotāju bāzei.
Kas ir kritiskais renderēšanas ceļš?
Kritiskais renderēšanas ceļš ir soļu secība, kas pārlūkprogrammai jāveic, lai pārvērstu HTML, CSS un JavaScript redzamos pikseļos uz ekrāna. CRP optimizācijas galvenais mērķis ir pēc iespējas ātrāk renderēt lietotājam sākotnējo, "virs locījuma" (above-the-fold) saturu. Jo ātrāk tas notiek, jo ātrāk lietotājs uztver lapas ielādi.
Šis ceļš sastāv no vairākiem galvenajiem posmiem:
- DOM izveide: Process sākas, kad pārlūkprogramma no servera saņem pirmos HTML dokumenta baitus. Tā sāk parsēt HTML marķējumu, rakstzīmi pēc rakstzīmes, un veido Dokumenta objektu modeli (DOM). DOM ir kokveida struktūra, kas attēlo visus HTML dokumenta mezglus (elementus, atribūtus, tekstu).
- CSSOM izveide: Kad pārlūkprogramma veido DOM, ja tā sastopas ar CSS stila lapu (vai nu
<link>tagā, vai iekļautā<style>blokā), tā sāk veidot CSS objektu modeli (CSSOM). Līdzīgi kā DOM, CSSOM ir koka struktūra, kas satur visus lapas stilus un to attiecības. Atšķirībā no HTML, CSS pēc noklusējuma ir renderēšanu bloķējošs. Pārlūkprogramma nevar renderēt nevienu lapas daļu, kamēr tā nav lejupielādējusi un parsējusi visu CSS, jo vēlāki stili varētu pārrakstīt agrākos. - Renderēšanas koka izveide: Tiklīdz gan DOM, gan CSSOM ir gatavi, pārlūkprogramma tos apvieno, lai izveidotu renderēšanas koku. Šis koks satur tikai tos mezglus, kas nepieciešami lapas renderēšanai. Piemēram, elementi ar
display: none;un<head>tags netiek iekļauti renderēšanas kokā, jo tie netiek vizuāli renderēti. Renderēšanas koks zina, ko attēlot, bet ne kur vai cik lielu. - Izkārtojums (Layout vai Reflow): Kad renderēšanas koks ir izveidots, pārlūkprogramma pāriet uz izkārtojuma posmu. Šajā solī tā aprēķina katra mezgla precīzu izmēru un pozīciju renderēšanas kokā attiecībā pret skatlogu. Šī posma rezultāts ir "box model", kas fiksē katra lapas elementa precīzu ģeometriju.
- Zīmēšana (Paint): Visbeidzot, pārlūkprogramma ņem izkārtojuma informāciju un "uzzīmē" pikseļus katram mezglam uz ekrāna. Tas ietver teksta, krāsu, attēlu, apmaļu un ēnu zīmēšanu — būtībā rasterizējot katru lapas vizuālo daļu. Šis process var notikt vairākos slāņos, lai uzlabotu efektivitāti.
- Kompozīcija (Composite): Ja lapas saturs tika zīmēts vairākos slāņos, pārlūkprogrammai ir jāsaliek šie slāņi pareizā secībā, lai parādītu galīgo attēlu uz ekrāna. Šis solis ir īpaši svarīgs animācijām un ritināšanai, jo kompozīcija parasti ir skaitļošanas ziņā mazāk prasīga nekā izkārtojuma un zīmēšanas posmu atkārtota izpilde.
JavaScript traucējošā loma kritiskajā renderēšanas ceļā
Tad kur šajā ainā iederas JavaScript? JavaScript ir jaudīga valoda, kas var modificēt gan DOM, gan CSSOM. Tomēr šai jaudai ir sava cena. JavaScript var, un bieži vien to arī dara, bloķēt kritisko renderēšanas ceļu, radot ievērojamas renderēšanas aizkaves.
Parseri bloķējošs JavaScript
Pēc noklusējuma JavaScript ir parseri bloķējošs. Kad pārlūkprogrammas HTML parseris sastopas ar <script> tagu, tam ir jāpārtrauc DOM veidošanas process. Pēc tam tas turpina lejupielādēt (ja tas ir ārējs), parsēt un izpildīt JavaScript failu. Šis process ir bloķējošs, jo skripts varētu izdarīt kaut ko līdzīgu document.write(), kas varētu mainīt visu DOM struktūru. Pārlūkprogrammai nav citas izvēles kā gaidīt, līdz skripts pabeigs darbu, pirms tā var droši atsākt HTML parsēšanu.
Ja šis skripts atrodas jūsu dokumenta <head> sadaļā, tas bloķē DOM izveidi pašā sākumā. Tas nozīmē, ka pārlūkprogrammai nav satura, ko renderēt, un lietotājs skatās uz baltu ekrānu, līdz skripts ir pilnībā apstrādāts. Tas ir galvenais sliktas uztvertās veiktspējas cēlonis.
DOM un CSSOM manipulācija
JavaScript var arī pieprasīt un modificēt CSSOM. Piemēram, ja jūsu skripts pieprasa aprēķinātu stilu, piemēram, element.style.width, pārlūkprogrammai vispirms ir jānodrošina, ka viss CSS ir lejupielādēts un parsēts, lai sniegtu pareizo atbildi. Tas rada atkarību starp jūsu JavaScript un jūsu CSS, kur skripta izpilde var tikt bloķēta, gaidot, kamēr CSSOM būs gatavs.
Turklāt, ja JavaScript modificē DOM (piemēram, pievieno vai noņem elementu) vai CSSOM (piemēram, maina klasi), tas var izraisīt pārlūkprogrammas darba kaskādi. Izmaiņas var piespiest pārlūkprogrammu pārrēķināt izkārtojumu (reflow) un pēc tam pārkrāsot (re-Paint) ietekmētās ekrāna daļas vai pat visu lapu. Biežas vai nepareizi ieplānotas manipulācijas var radīt lēnu, nereaģējošu lietotāja saskarni.
Kā analizēt kritisko renderēšanas ceļu
Pirms optimizācijas ir jāveic mērījumi. Pārlūkprogrammas izstrādātāju rīki (developer tools) ir jūsu labākais draugs CRP analīzē. Pievērsīsimies Chrome DevTools, kas piedāvā jaudīgu rīku komplektu šim mērķim.
Performance cilnes izmantošana
Performance cilne nodrošina detalizētu laika grafiku par visu, ko pārlūkprogramma dara, lai renderētu jūsu lapu.
- Atveriet Chrome DevTools (Ctrl+Shift+I vai Cmd+Option+I).
- Dodieties uz cilni Performance.
- Pārliecinieties, ka ir atzīmēta izvēles rūtiņa "Web Vitals", lai redzētu galvenos rādītājus laika grafikā.
- Noklikšķiniet uz pārlādes pogas (vai nospiediet Ctrl+Shift+E / Cmd+Shift+E), lai sāktu lapas ielādes profilēšanu.
Pēc lapas ielādes jums tiks parādīta liesmu diagramma (flame chart). Lūk, kam jāpievērš uzmanība Main pavediena sadaļā:
- Ilgie uzdevumi (Long Tasks): Jebkurš uzdevums, kas ilgst vairāk nekā 50 milisekundes, ir atzīmēts ar sarkanu trīsstūri. Tie ir galvenie optimizācijas kandidāti, jo tie bloķē galveno pavedienu un var padarīt lietotāja saskarni nereaģējošu.
- HTML parsēšana (Parse HTML - zils): Tas parāda, kur pārlūkprogramma parsē jūsu HTML. Ja redzat lielas spraugas vai pārtraukumus, tas, visticamāk, ir bloķējoša skripta dēļ.
- Skripta izvērtēšana (Evaluate Script - dzeltens): Šeit tiek izpildīts JavaScript. Meklējiet garus dzeltenus blokus, īpaši lapas ielādes sākumā. Tie ir jūsu bloķējošie skripti.
- Stila pārrēķināšana (Recalculate Style - violets): Tas norāda uz CSSOM izveidi un stila aprēķiniem.
- Izkārtojums (Layout - violets): Šie bloki attēlo izkārtojuma vai reflow posmu. Ja redzat daudz šādu bloku, jūsu JavaScript, iespējams, izraisa "izkārtojuma tricināšanu" (layout thrashing), atkārtoti lasot un rakstot ģeometriskās īpašības.
- Zīmēšana (Paint - zaļš): Šis ir zīmēšanas process.
Network cilnes izmantošana
Network cilnes ūdenskrituma diagramma (waterfall chart) ir nenovērtējama, lai izprastu resursu lejupielādes secību un ilgumu.
- Atveriet DevTools un dodieties uz cilni Network.
- Pārlādējiet lapu.
- Ūdenskrituma skats parāda, kad katrs resurss (HTML, CSS, JS, attēli) tika pieprasīts un lejupielādēts.
Pievērsiet īpašu uzmanību pieprasījumiem ūdenskrituma augšpusē. Jūs varat viegli pamanīt CSS un JavaScript failus, kas tiek lejupielādēti, pirms lapa sāk renderēties. Tie ir jūsu renderēšanu bloķējošie resursi.
Lighthouse izmantošana
Lighthouse ir automatizēts audita rīks, kas iebūvēts Chrome DevTools (zem Lighthouse cilnes). Tas nodrošina augsta līmeņa veiktspējas novērtējumu un praktiskus ieteikumus.
Galvenais CRP audits ir "Novērst renderēšanu bloķējošos resursus." Šis ziņojums skaidri uzskaitīs CSS un JavaScript failus, kas aizkavē pirmo satura zīmējumu (First Contentful Paint - FCP), sniedzot jums skaidru optimizācijas mērķu sarakstu.
JavaScript pamata optimizācijas stratēģijas
Tagad, kad zinām, kā identificēt problēmas, izpētīsim risinājumus. Mērķis ir samazināt JavaScript daudzumu, kas bloķē sākotnējo renderēšanu.
1. `async` un `defer` spēks
Vienkāršākais un efektīvākais veids, kā novērst JavaScript bloķēšanu HTML parserim, ir izmantot `async` un `defer` atribūtus jūsu <script> tagos.
- Standarta
<script>:<script src="script.js"></script>
Kā jau mēs apspriedām, tas ir parseri bloķējošs. HTML parsēšana apstājas, skripts tiek lejupielādēts un izpildīts, un pēc tam parsēšana atsākas. <script async>:<script src="script.js" async></script>
Skripts tiek lejupielādēts asinhroni, paralēli HTML parsēšanai. Tiklīdz skripts pabeidz lejupielādi, HTML parsēšana tiek apturēta un skripts tiek izpildīts. Izpildes secība nav garantēta; skripti tiek izpildīti, kad tie kļūst pieejami. Tas ir labākais risinājums neatkarīgiem, trešo pušu skriptiem, kas nav atkarīgi no DOM vai citiem skriptiem, piemēram, analītikas vai reklāmas skriptiem.<script defer>:<script src="script.js" defer></script>
Skripts tiek lejupielādēts asinhroni, paralēli HTML parsēšanai. Tomēr skripts tiek izpildīts tikai pēc tam, kad HTML dokuments ir pilnībā parsēts (tieši pirms `DOMContentLoaded` notikuma). Skriptiem ar `defer` tiek garantēta arī izpilde tādā secībā, kādā tie parādās dokumentā. Šī ir vēlamā metode lielākajai daļai skriptu, kam nepieciešams mijiedarboties ar DOM un kas nav kritiski svarīgi sākotnējai zīmēšanai.
Vispārīgs noteikums: Izmantojiet `defer` saviem galvenajiem lietojumprogrammas skriptiem. Izmantojiet `async` neatkarīgiem trešo pušu skriptiem. Izvairieties no bloķējošu skriptu izmantošanas <head> sadaļā, ja vien tie nav absolūti nepieciešami sākotnējai renderēšanai.
2. Koda sadalīšana (Code Splitting)
Mūsdienu tīmekļa lietojumprogrammas bieži tiek apvienotas vienā lielā JavaScript failā. Lai gan tas samazina HTTP pieprasījumu skaitu, tas liek lietotājam lejupielādēt daudz koda, kas var nebūt nepieciešams sākotnējam lapas skatam.
Koda sadalīšana ir process, kurā šis lielais fails tiek sadalīts mazākos gabalos, kurus var ielādēt pēc pieprasījuma. Piemēram:
- Sākotnējais gabals (Initial Chunk): Satur tikai būtisko JavaScript, kas nepieciešams, lai renderētu redzamo pašreizējās lapas daļu.
- Pēc pieprasījuma ielādējamie gabali (On-Demand Chunks): Satur kodu citiem maršrutiem, modālajiem logiem vai funkcijām, kas atrodas zem locījuma. Tie tiek ielādēti tikai tad, kad lietotājs pāriet uz šo maršrutu vai mijiedarbojas ar funkciju.
Mūsdienu saiņotāji (bundlers), piemēram, Webpack, Rollup un Parcel, ir iebūvējuši atbalstu koda sadalīšanai, izmantojot dinamisku `import()` sintaksi. Ietvari, piemēram, React (ar `React.lazy`) un Vue, arī nodrošina vienkāršus veidus, kā sadalīt kodu komponentu līmenī.
3. Tree Shaking un nelietotā koda likvidēšana
Pat ar koda sadalīšanu jūsu sākotnējais fails var saturēt kodu, kas faktiski netiek izmantots. Tas ir bieži sastopams, kad importējat bibliotēkas, bet izmantojat tikai nelielu to daļu.
Tree Shaking ir process, ko izmanto mūsdienu saiņotāji, lai no jūsu galīgā faila likvidētu neizmantoto kodu. Tas statiski analizē jūsu `import` un `export` priekšrakstus un nosaka, kurš kods ir nesasniedzams. Nodrošinot, ka jūs piegādājat tikai to kodu, kas nepieciešams jūsu lietotājiem, jūs varat ievērojami samazināt failu izmērus, kas noved pie ātrākas lejupielādes un parsēšanas laika.
4. Minifikācija un kompresija
Šie ir fundamentāli soļi jebkurai produkcijas vietnei.
- Minifikācija: Tas ir automatizēts process, kas no jūsu koda noņem nevajadzīgās rakstzīmes — piemēram, atstarpes, komentārus un jaunas rindas — un saīsina mainīgo nosaukumus, nemainot tā funkcionalitāti. Tas samazina faila izmēru. Bieži tiek izmantoti rīki, piemēram, Terser (JavaScript) un cssnano (CSS).
- Kompresija: Pēc minifikācijas jūsu serverim ir jāsaspiež faili pirms to nosūtīšanas uz pārlūkprogrammu. Algoritmi, piemēram, Gzip un, vēl efektīvāk, Brotli, var samazināt failu izmērus par līdz pat 70-80%. Pārlūkprogramma tos pēc saņemšanas atspiež. Šī ir servera konfigurācija, bet tā ir ļoti svarīga, lai samazinātu tīkla pārsūtīšanas laiku.
5. Kritiski svarīgā JavaScript iekļaušana (izmantot piesardzīgi)
Ļoti maziem JavaScript fragmentiem, kas ir absolūti nepieciešami pirmajai zīmēšanai (piemēram, tēmas iestatīšanai vai kritiski svarīgam polyfill), jūs varat tos iekļaut tieši savā HTML <script> tagā <head> sadaļā. Tas ietaupa tīkla pieprasījumu, kas var būt noderīgi mobilajos savienojumos ar lielu latentumu. Tomēr to vajadzētu izmantot taupīgi. Iekļautais kods palielina jūsu HTML dokumenta izmēru, un pārlūkprogramma to nevar kešot atsevišķi. Tas ir kompromiss, kas rūpīgi jāapsver.
Progresīvas metodes un mūsdienu pieejas
Servera puses renderēšana (SSR) un statiskā vietņu ģenerēšana (SSG)
Ietvari, piemēram, Next.js (React), Nuxt.js (Vue) un SvelteKit, ir popularizējuši SSR un SSG. Šīs metodes pārnes sākotnējo renderēšanas darbu no klienta pārlūkprogrammas uz serveri.
- SSR: Serveris renderē pilnu HTML pieprasītajai lapai un nosūta to uz pārlūkprogrammu. Pārlūkprogramma var nekavējoties parādīt šo HTML, kas nodrošina ļoti ātru pirmo satura zīmējumu. Pēc tam JavaScript ielādējas un "hidratē" lapu, padarot to interaktīvu.
- SSG: HTML katrai lapai tiek ģenerēts būvēšanas laikā (build time). Kad lietotājs pieprasa lapu, statisks HTML fails tiek nekavējoties pasniegts no CDN. Tā ir ātrākā pieeja ar saturu bagātām vietnēm.
Gan SSR, gan SSG krasi uzlabo CRP veiktspēju, nodrošinot jēgpilnu pirmo zīmējumu, pirms lielākā daļa klienta puses JavaScript ir pat sākusi izpildi.
Web Workers
Ja jūsu lietojumprogrammai ir jāveic smagi, ilgi skaitļošanas darbi (piemēram, sarežģīta datu analīze, attēlu apstrāde vai kriptogrāfija), to darīšana galvenajā pavedienā bloķēs renderēšanu un liks jūsu lapai šķist iesaldētai. Web Workers nodrošina risinājumu, ļaujot jums palaist šos skriptus fona pavedienā, pilnīgi atsevišķi no galvenā UI pavediena. Tas uztur jūsu lietojumprogrammu atsaucīgu, kamēr smagais darbs notiek aizkulisēs.
Praktiska darba plūsma CRP optimizācijai
Apvienosim to visu praktiskā darba plūsmā, ko varat pielietot savos projektos.
- Audits: Sāciet ar bāzes līniju. Palaidiet Lighthouse ziņojumu un Performance profilu savai produkcijas versijai, lai saprastu savu pašreizējo stāvokli. Pierakstiet savus FCP, LCP, TTI rādītājus un identificējiet visus ilgos uzdevumus vai renderēšanu bloķējošos resursus.
- Identifikācija: Iedziļinieties DevTools Network un Performance cilnēs. Precīzi nosakiet, kuri skripti un stila lapas bloķē sākotnējo renderēšanu. Uzdodiet sev jautājumu par katru resursu: "Vai tas ir absolūti nepieciešams, lai lietotājs redzētu sākotnējo saturu?"
- Prioritizēšana: Koncentrējiet savus centienus uz kodu, kas ietekmē saturu virs locījuma. Mērķis ir pēc iespējas ātrāk nogādāt šo saturu lietotājam. Viss pārējais var tikt ielādēts vēlāk.
- Optimizācija:
- Pielietojiet
defervisiem nebūtiskiem skriptiem. - Izmantojiet
asyncneatkarīgiem trešo pušu skriptiem. - Ieviesiet koda sadalīšanu saviem maršrutiem un lieliem komponentiem.
- Nodrošiniet, ka jūsu būvēšanas process ietver minifikāciju un tree shaking.
- Sadarbojieties ar savu infrastruktūras komandu, lai iespējotu Brotli vai Gzip kompresiju jūsu serverī.
- Attiecībā uz CSS apsveriet iespēju iekļaut kritiski svarīgo CSS, kas nepieciešams sākotnējam skatam, un pārējo ielādēt vēlāk (lazy-loading).
- Pielietojiet
- Mērīšana: Pēc izmaiņu ieviešanas palaidiet auditu vēlreiz. Salīdziniet savus jaunos rādītājus un laikus ar bāzes līniju. Vai jūsu FCP ir uzlabojies? Vai ir mazāk renderēšanu bloķējošu resursu?
- Iterācija: Tīmekļa veiktspēja nav vienreizējs labojums; tas ir nepārtraukts process. Jūsu lietojumprogrammai augot, var parādīties jaunas veiktspējas vājās vietas. Padariet veiktspējas auditu par regulāru savas izstrādes un izvietošanas cikla daļu.
Noslēgums: ceļa uz veiktspēju apgūšana
Kritiskais renderēšanas ceļš ir plāns, ko pārlūkprogramma seko, lai atdzīvinātu jūsu lietojumprogrammu. Kā izstrādātājiem mūsu izpratne un kontrole pār šo ceļu, īpaši attiecībā uz JavaScript, ir viena no spēcīgākajām svirām, kas mums ir, lai uzlabotu lietotāja pieredzi. Pārejot no domāšanas veida, kurā vienkārši rakstām kodu, kas darbojas, uz kodu, kas ir veiktspējīgs, mēs varam veidot lietojumprogrammas, kas ir ne tikai funkcionālas, bet arī ātras, pieejamas un patīkamas lietotājiem visā pasaulē.
Ceļojums sākas ar analīzi. Atveriet savus izstrādātāju rīkus, profilējiet savu lietojumprogrammu un sāciet apšaubīt katru resursu, kas stāv starp jūsu lietotāju un pilnībā renderētu lapu. Pielietojot skriptu atlikšanas, koda sadalīšanas un datu apjoma samazināšanas stratēģijas, jūs varat atbrīvot ceļu pārlūkprogrammai, lai tā darītu to, ko tā prot vislabāk: renderēt saturu zibens ātrumā.